#include <LiquidCrystal_I2C.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "OneWire.h" 
#include <DallasTemperature.h>
#include <Wire.h>

int tan_one = 13 ;
int cooler = 14;
int power = 0;
int relay_timing_ok = 1; 

const char* ssid = ""; 
const char* password = "";
const char* mqttServer = ""; 
const int mqttPort = 1883;
WiFiClient espClient; 
PubSubClient client(espClient); 

int temp = 0; 
int old_temp = 0; 
int temp_radiator = 0; 
int hysteresis = 7; 
int relay_global_status = 0;
int cooler_is_enabled = 1; 
int heater_status = 0;
int heater_status_old; 
OneWire ds(12);
DallasTemperature sensors(&ds);
LiquidCrystal_I2C lcd(0x27,16,2); 


 void TempSend()
 {
      String param = String(temp);
      char __param[sizeof(param)];
      param.toCharArray(__param, sizeof(__param));
      client.publish("wemos/temp",__param);
      String param_radiator = String(temp_radiator);
      char __param_radiator[sizeof(param_radiator)];
      param_radiator.toCharArray(__param_radiator, sizeof(__param_radiator));
      client.publish("wemos/temp_radiator",__param_radiator);
      String param_heater = String(heater_status);
      char __param_heater[sizeof(param_heater)];
      param_heater.toCharArray(__param_heater, sizeof(__param_heater));
      client.publish("wemos/heater",__param_heater);
      
 }
 

void setup() {
  
  Serial.begin(115200);
  lcd.begin(); // Инициализация lcd
  lcd.backlight(); // Включаем подсветку
  lcd.print("Loading"); // Выводим текст
  lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
  lcd.print("Wait..."); // Выводим текст
  lcd.clear();
  delay (2000);
  
  //  pinMode(BUTTON_PIN, INPUT);
  pinMode(tan_one, OUTPUT);
  pinMode(cooler, OUTPUT);
  
  analogWrite(tan_one, power);
  digitalWrite(cooler, HIGH);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  
  client.setServer(mqttServer, mqttPort);
  //client.setCallback(callback);
  sensors.begin();
}
void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    char __value[sizeof(payload)];
    
    if (strcmp(topic,"wemos/relay")==0) {
      //переводим байты в массив символов
      for (int i = 0; i < length; i++) {
           __value[i] = (char)payload[i];
     }
    // массив символов в целое число
    int IntVar;
    IntVar = atoi(__value);
    Serial.print("integer value: ");
    Serial.println(IntVar);
    hysteresis = IntVar;
 
    client.publish("wemos/relay_status",__value);
 } 
 if (strcmp(topic,"wemos/relay_timing")==0) {
      //переводим байты в массив символов
      for (int i = 0; i < length; i++) {
           __value[i] = (char)payload[i];
     }
    // массив символов в целое число
    int IntVar;
    IntVar = atoi(__value);
    Serial.print("integer value: ");
    Serial.println(IntVar);
    relay_timing_ok = IntVar;
    
  } 
  
  Serial.println();
  Serial.println("-----------------------");
}
void loop() {

  int delta = hysteresis-3;
  sensors.requestTemperatures();
  temp = sensors.getTempCByIndex(1);
  temp_radiator = sensors.getTempCByIndex(0);
  heater_status = analogRead(tan_one);

	Serial.println(relay_timing_ok);
      lcd.setCursor(0, 0);
      lcd.print(" ");
      lcd.setCursor(0, 0);
      lcd.print(temp);
      lcd.print(" [");
      lcd.print(delta-1);
      lcd.print("->");
      lcd.print(hysteresis);
      lcd.print("]");
      old_temp = temp;
  
     lcd.setCursor(0, 1);
     lcd.print(" ");
     lcd.setCursor(0, 1);
     lcd.print(temp_radiator);
     lcd.print("[");
     if (relay_timing_ok == 0){
         lcd.print("NOT TIME");}
     if (relay_timing_ok == 1){
          lcd.print("HEATING TIME");}
     lcd.print("]");
      
  
  //аварийная остановка если тэн перегрелся + включение вентилятора
  if (temp >= 50){
    analogWrite(tan_one, 0);
    digitalWrite(cooler, LOW);
 }
  
  // включение вентилятора при перегреве реле
  if (temp_radiator >= 50){
    digitalWrite(cooler, LOW);
  }
  //включение вентилятора + аварийная остановка тэна и реле,если реле перегрелось
  if (temp_radiator > 60){
    analogWrite(tan_one, 0);
    digitalWrite(cooler, LOW);
  }
  
 // включаем вентилятор, если плата запущена при уже нагретом реле и выключенном тэне (при перезапуске или старте платы)
  if (temp_radiator >= 30 && relay_global_status == 0){
    digitalWrite(cooler, LOW);
   }
   else
   {
    // система считается запущенной, радиатор остывшим
      relay_global_status = 1;
   } 
// если радиатор холодный и тэн выключен, то выключаем вентилятор
  if (temp_radiator < 30 && heater_status == 0){
    digitalWrite(cooler, HIGH);
  } 
   
  // подогреваем если меньше заданного
  // !ВКЛЮЧАЕМ тэн и вентилятор, если температура меньше заданной-3 и радиатор реле остывший
  if(temp < delta && temp_radiator < 35 && relay_timing_ok == 1){
    analogWrite(tan_one, 1024);
    digitalWrite(cooler, LOW);
  }
  // если температура достигла заданного значения - выключаем тэн и вентилятор
  if(temp >= hysteresis){
    analogWrite(tan_one, 0);
    digitalWrite(cooler, HIGH);
  }
 if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
      Serial.println("WiFi connected");
      }
  // подключаемся к MQTT серверу
  if (WiFi.status() == WL_CONNECTED) {
    if (!client.connected())
    {
     Serial.println("Connecting to MQTT server");
      if (client.connect("wemos"))
      {
       Serial.println("Connected to MQTT server");
       client.setCallback(callback);
       
       client.subscribe("wemos/relay");
       client.subscribe("wemos/relay_timing");
      }
       else
      {
        Serial.println("Could not connect to MQTT server");
      }
    }
 }
 
  if (client.connected())
  {
   client.loop();
   TempSend();
  }
} // конец основного цикла
